package cn.takujo.simple.elasticsearch.client;

import java.util.Map;
import java.util.Set;

import lombok.Getter;

/**
 * Es mapping 构建器<br>
 * 包含简单类型和嵌套文档的复合类型
 * 
 * @author wzx
 * @date 2019年4月2日 下午2:52:42
 * @Description 项目:takujo-simple-elasticsearch-client
 */
public class MappingBuilder {

	public String build(Map<String, MetaProperty> metas) {
		String pros = "\"properties\":{";
		if (metas == null || metas.isEmpty()) {
			pros = pros + "}";
		} else {
			StringBuffer sb = new StringBuffer();
			Set<String> keySet = metas.keySet();
			for (String key : keySet) {
				String meta = meta(key, metas.get(key));
				sb.append(meta + ",");
			}
			sb.deleteCharAt(sb.length() - 1);
			pros = pros + sb.toString() + "}";
		}
		return "\"mappings\": {\"doc\": {" + "\"dynamic\": \"strict\"," + pros + "}}";
	}

	private String meta(String key, MetaProperty meta) {
		if (meta.isComplex()) {
			Map<String, EsFieldType> complex = meta.getComplex();
			return complex(key, complex);
		} else {
			EsFieldType type = meta.getType();
			return handleEsFieldType(key, type);
		}
	}

	private String complex(String key, Map<String, EsFieldType> map) {
		String pros = "\"properties\":{";
		if (map == null || map.isEmpty()) {
			pros = pros + "}";
		}
		StringBuffer sb = new StringBuffer();
		Set<String> keySet = map.keySet();
		for (String ke : keySet) {
			sb.append(handleEsFieldType(ke, map.get(ke)) + ",");
		}
		sb.deleteCharAt(sb.length() - 1);
		pros = pros + sb.toString() + "}";
		return doubleQuotes() + key + doubleQuotes() + colon() + leftBrace() + pros + rightBrace();
	}

	private String handleEsFieldType(String key, EsFieldType type) {
		String value = type.value();
		String init = doubleQuotes() + key + doubleQuotes() + colon() + leftBrace() + doubleQuotes() + "type"
				+ doubleQuotes() + colon() + doubleQuotes() + value + doubleQuotes();
		return init + rightBrace();
	}

	private String doubleQuotes() {
		return "\"";
	}

	private String colon() {
		return ":";
	}

	private String rightBrace() {
		return "}";
	}

	private String leftBrace() {
		return "{";
	}

	public static class MetaProperty {

		@Getter
		private EsFieldType type;
		@Getter
		private Map<String, EsFieldType> complex;
		private boolean isComplex = false;

		public MetaProperty(EsFieldType type) {
			this.type = type;
		}

		public MetaProperty(Map<String, EsFieldType> complex) {
			this.complex = complex;
			isComplex = true;
		}

		public boolean isComplex() {
			return isComplex;
		}

	}

}
